/**
 * 相似度对比
 * @param s 文本1
 * @param t 文本2
 * @param f 小数位精确度，默认2位
 * @returns {string|number|*} 百分数前的数值，最大100. 比如 ：90.32
 */
export function similarTs(
  s: string,
  t: string,
  f: string | number = 2
): number {
  let result: number = 0;
  // 有一个字符串不存在则返回0
  if (!s || !t) return 0;
  //保证t 比s长
  if (s.length > t.length) [s, t] = [t, s];
  // 有效位数变成数字，错误则为2
  f = !isNaN(Number(f)) ? Number(f) : 2;
  // 记录相同数字的协同数
  let diffArr: number[][] = [];
  // 初始化,增加一个单元格使 diffArr行列各加一，s为行，t为列 diffArr[s_idx][t_idx]=s_idx+t_idx
  diffArr = Array.from("0" + s).map((s_char, s_idx) =>
    Array.from("0" + t).map((t_char, t_idx) => s_idx + t_idx)
  );
  Array.from(s).forEach((s_char, s_idx) => {
    Array.from(t).forEach(
      (t_char, t_idx) =>
        (diffArr[s_idx + 1][t_idx + 1] =
          // 左上角 上  左 的最小值
          Math.min(
            diffArr[s_idx][t_idx],
            diffArr[s_idx + 1][t_idx],
            diffArr[s_idx][t_idx + 1]
          ) +
          //相等为0
          Number(s_char !== t_char))
    );
  });
  // console.table(diffArr);
  result = Number((1 - diffArr[s.length][t.length] / t.length).toFixed(f));
  return result;
}

/**
 * 相似度对比
 * @requires similarTs|similarJS
 * @param t 文本2
 * @param sArr 文本数组
 * @param cfg 十位数：相似度,个位数：最似值；余数排序
 * @param f 小数位精确度，默认2位
 * @returns {string|number|*} 百分数前的数值，最大100. 比如 ：90.32
 */
export function similarMostTs(
  t: string,
  sArr: string[],
  cfg: number = 0,
  f: number | string = 2
): number | string {
  let result: number | string = 0;
  let simArr = sArr.map((item) => ({
    相似度: similarTs(item, t, f),
    最似值: item,
  }));
  let simArrSort = simArr.sort((a, b) => (a.相似度 > b.相似度 ? -1 : 1));
  if (cfg < 10) {
    result = simArrSort[Math.min(cfg % 10, simArrSort.length - 1)].最似值;
  } else {
    result = simArrSort[Math.min(cfg % 10, simArrSort.length - 1)].相似度;
  }
  return result;
}

export function similarMostTsObject(
  t: string,
  sArr: string[],
  cfg: number = 0,
  f: number | string = 2
) {
  let result: number | string = 0;
  let simArr = sArr.map((item) => ({
    相似度: similarTs(item, t, f),
    最似值: item,
  }));
  let simArrSort = simArr.sort((a, b) => (a.相似度 > b.相似度 ? -1 : 1));
  return simArrSort;
}

/**
 * 相似度对比
 * @param s 文本1数组
 * @param t 文本2数组
 * @param f 小数位精确度，默认2位
 * @returns {string|number|*} 百分数前的数值，最大100. 比如 ：90.32
 */
export function similarTsSuper(
  s: string[],
  t: string[],
  f: string | number = 2
): number {
  let result: number = 0;
  // 有一个为[]不存在则返回0
  if (s.length === 0 || t.length === 0) return 0;
  //保证t 比s长
  if (s.length > t.length) [s, t] = [t, s];
  // 有效位数变成数字，错误则为2
  f = !isNaN(Number(f)) ? Number(f) : 2;
  // 记录相同数字的协同数
  let diffArr: number[][] = [];
  // 初始化,增加一个单元格使 diffArr行列各加一，s为行，t为列 diffArr[s_idx][t_idx]=s_idx+t_idx
  diffArr = Array.from(["0"].concat(...s)).map((s_char, s_idx) =>
    Array.from(["0"].concat(...t)).map((t_char, t_idx) => s_idx + t_idx)
  );
  Array.from(s).forEach((s_char, s_idx) => {
    Array.from(t).forEach(
      (t_char, t_idx) =>
        (diffArr[s_idx + 1][t_idx + 1] =
          // 左上角 上  左 的最小值
          Math.min(
            diffArr[s_idx][t_idx],
            diffArr[s_idx + 1][t_idx],
            diffArr[s_idx][t_idx + 1]
          ) +
          //相等为0
          Number(s_char !== t_char))
    );
  });
  // console.table(diffArr);
  result = Number((1 - diffArr[s.length][t.length] / t.length).toFixed(f));
  return result;
}

export function similarMostTsSuper(
  t: string[],
  sArr: string[][],
  cfg: number = 0, //十位数：相似度,个位数：最似值；余数排序
  f: number | string = 2
): Array<number | string> {
  let result: Array<number | string> = [];
  let simArr = sArr.map((item) => ({
    相似度: similarTsSuper(item, t, f),
    最似值: item.join(),
  }));
  let simArrSort = simArr.sort((a, b) => (a.相似度 > b.相似度 ? -1 : 1));
  if (cfg < 10) {
    result.push(simArrSort[Math.min(cfg % 10, simArrSort.length - 1)].最似值);
  } else {
    result.push(simArrSort[Math.min(cfg % 10, simArrSort.length - 1)].相似度);
  }
  return result;
}

export function similarMostTsObjectSuper(
  t: string[],
  sArr: string[][],
  cfg: number = 0,
  f: number | string = 2
) {
  let simArr = sArr.map((item) => ({
    相似度: similarTsSuper(item, t, f),
    最似值: item.join(""),
  }));
  let simArrSort = simArr.sort((a, b) => (a.相似度 > b.相似度 ? -1 : 1));
  return simArrSort;
}
